package com.jweb.framework.http.support;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationObjectSupport;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;

/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明：视图解析
 */
public class MimeTypesViewResolver extends WebApplicationObjectSupport implements Ordered , ViewResolver {
	
	private static final Logger logger = LoggerFactory.getLogger(MimeTypesViewResolver.class);
	private int order = -2147483648;
	private boolean useNotAcceptableStatusCode = false ;
	private List<View> defaultViews ;
	private List<ViewResolver> viewResolvers ;
	private static MimeTypes mimeTypes = new MimeTypes();
	
	private static final View view = new DefView();
	
	public void setOrder(int order){
		this.order = order ;
	}

	public int getOrder() {
		
		return this.order ;
	}
	
	public void setUseNotAcceptableStatusCode(boolean flag){
		this.useNotAcceptableStatusCode = flag ;
	}
	
	public void setDefaultViews(List<View> list){
		this.defaultViews = list ;
	}
	
	public void setViewResolvers(List<ViewResolver> list){
		this.viewResolvers = list ;
	}
	
    protected void initServletContext(ServletContext servletContext){
		
		Iterator it ;
		Object obj ;
		Map<String, ViewResolver> map ;
		if(this.viewResolvers == null){
			map = BeanFactoryUtils.beansOfTypeIncludingAncestors(getApplicationContext(), ViewResolver.class);
			this.viewResolvers = new ArrayList<ViewResolver>(map.size());
			for(it = map.values().iterator() ; it.hasNext() ;){
				obj = it.next();
				if(this != obj){
					this.viewResolvers.add((ViewResolver) obj);
				}
			}
		}
		
		if(this.viewResolvers.isEmpty()){
			logger.warn("Did not find any ViewResolvers to delegate to ; please configure them using the  'viewResolvers' property on the ContentNegotiatingViewResolver");
		}
		
		OrderComparator.sort(this.viewResolvers);
		
		Map map1 ;
		if(this.defaultViews == null){
			map1 = BeanFactoryUtils.beansOfTypeIncludingAncestors(getApplicationContext(), View.class);
			this.defaultViews = new ArrayList<View>(map1.size());
			for(it = map1.values().iterator() ; it.hasNext() ;){
				obj = it.next();
				this.defaultViews.add((View) obj);
			}
		}
		OrderComparator.sort(this.defaultViews);
		
		Map map2 = BeanFactoryUtils.beansOfTypeIncludingAncestors(getApplicationContext(), MimeTypes.class);
		if(map2.size()>0){
			this.mimeTypes = (MimeTypes) map2.values().iterator().next();
		}
		
	}
	
	/**根据视图名解析视图*/
	public View resolveViewName(String viewName , Locale locale) throws Exception {
		
		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
		Assert.isInstanceOf(ServletRequestAttributes.class , requestAttributes);
		ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
		
		List list = null ;
		MediaType mediaType = this.mimeTypes.getMediaTypeFromFilename(viewName);
		if(mediaType != null){
			list = Collections.singletonList(mediaType);
		}
		else {
			list = this.mimeTypes.getMediaTypes(servletRequestAttributes.getRequest());
		}
		
		ArrayList arrayList = new ArrayList();
		Object obj3 ;
		for(Iterator it = this.viewResolvers.iterator() ; it.hasNext() ; ){
			ViewResolver obj1 = (ViewResolver) it.next() ;
			obj3 = ((ViewResolver)obj1).resolveViewName(viewName,  locale);
			if(obj3 != null){
				arrayList.add(obj3);
			}
		}
		
		if(!CollectionUtils.isEmpty(this.defaultViews)){
			arrayList.addAll(this.defaultViews);
		}
		
		Object obj1 = null ;
		Object obj2 = null ;
		for(Iterator it = list.iterator() ; it.hasNext() ;){
			obj3 = it.next() ;
			for(View view : (ArrayList<View>)arrayList){
				if(StringUtils.hasText(view.getContentType())){
					MediaType mediaType2 = MediaType.parseMediaType(view.getContentType());
					if(((MediaType)obj3).includes(mediaType2)){
						obj1 = obj3 ;
						obj2 = view ;
						break ;
					}
				}
			}
			
			if(obj2 != null){
				break ;
			}
		}
		
		if(obj2 != null){
			if(logger.isDebugEnabled()){
				logger.debug("Returning [" + obj2 + "] based on requested media type '" + obj1 + "'");
			}
			return (View)obj2 ;
		}
		if(this.useNotAcceptableStatusCode){
			if(logger.isDebugEnabled()){
				logger.debug("No acceptable view found; returning 406 (Not Acceptable) status code");
			}
			return view ;
		}
		if(logger.isDebugEnabled()){
			logger.debug("No acceptable view found; returning null");
		}
		
		return (View)null;
		
	}
    
    
	
}
